package com.du.web.sample.util.water;

import cn.hutool.core.io.FileUtil;
import lombok.extern.slf4j.Slf4j;

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;

/**
 * @desc:
 * @author: shuangdu
 * @date: 2021/9/15
 * @since: 1.8
 */
@Slf4j
public class PicWaterMaker extends WaterMaker {

    public PicWaterMaker (WaterMakeParam waterMakeParam) {
        super(waterMakeParam);
        this.initPicParam();
    }

    private void initPicParam() {
        if (waterMakeParam.getPicFormatName() == null) {
            waterMakeParam.setPicFormatName(WaterMakeParam.PicFormatName.JPG);
            waterMakeParam.setExtName("jpg");
        } else {
            waterMakeParam.setExtName(FileUtil.extName(waterMakeParam.getFileName()).toLowerCase());
        }
        // 输出名称
        waterMakeParam.setOutFileName(makeOutFileName());

        //
        outSrcPath = outSrcPath.concat(waterMakeParam.getOutFileName());
    }

    @Override
    public void doMake() {
        OutputStream os = null;
        // 设置水印文字的旋转角度
        // 问题：角度变换可能导致水印无法铺满图片
        int degree = waterMakeParam.getDegree();
        // 设置水印透明度 默认为1.0  值越小颜色越浅
        float alpha = waterMakeParam.getAlpha();
        Font font = new Font("微软雅黑", Font.PLAIN, waterMakeParam.getFontSize());
        Color color = new Color(200, 200, 200, 180);
        String waterContent = new String(waterMakeParam.getWaterContent().getBytes(), StandardCharsets.UTF_8);
        try {
            Image srcImg = ImageIO.read(waterMakeParam.getWaterInputStream());
            int srcImgWidth = srcImg.getWidth(null);
            int srcImgHeight = srcImg.getHeight(null);
            // 加水印
            BufferedImage bufImg = new BufferedImage(srcImgWidth, srcImgHeight, BufferedImage.TYPE_INT_RGB);
            Graphics2D g = bufImg.createGraphics();
            g.drawImage(srcImg, 10, 10, srcImgWidth, srcImgHeight, null);

            // 设置水印颜色
            g.setColor(color);
            // 设置水印字体
            g.setFont(font);

            //设置水印文字透明度
            g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));
            //设置水印旋转
            g.rotate(Math.toRadians(degree), (double) srcImgWidth / 2, (double) srcImgHeight / 2);

            JLabel label = new JLabel(waterContent);
            FontMetrics metrics = label.getFontMetrics(font);
            // 文字水印的宽
            int width = metrics.stringWidth(label.getText());
            // 图片的高  除以  文字水印的宽  打印的行数(以文字水印的宽为间隔)
            int rowsNumber = srcImgHeight / width + srcImgHeight % width;
            // 图片的宽 除以 文字水印的宽  每行打印的列数(以文字水印的宽为间隔)
            int columnsNumber = srcImgWidth / width + srcImgWidth % width;
            // 防止图片太小而文字水印太长，所以至少打印一次
            if (rowsNumber < 1) {
                rowsNumber = 1;
            }
            if (columnsNumber < 1) {
                columnsNumber = 1;
            }
            for (int j = 0; j < rowsNumber; j++) {
                for (int i = 0; i < columnsNumber; i++) {
                    // 画出水印,并设置水印位置
                    g.drawString(waterContent, i * width + j * width, -i * width + j * width);
                }
            }
            g.dispose();

            log.info("生成图片路径: {}", outSrcPath);
            os = new FileOutputStream(outSrcPath);

            // 生成图片
            ImageIO.write(bufImg, waterMakeParam.getPicFormatName().name(), os);

            log.info("图片完成添加水印...");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (null != os)
                    os.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}
